function deepClone(target, cache = new Map()) {
  if (cache.has(target)) return cache.get(target);
  if (target instanceof Object) {
    let dist;
    if (target instanceof Array) {
      dist = [];
    } else if (target instanceof Function) {
      dist = function () {
        return target.apply(this, ...arguments);
      };
    } else if (target instanceof RegExp) {
      dist = new RegExp(target.source, target.flags);
    } else if (target instanceof Date) {
      dist = new Date(target);
    }
    cache.set(target, dist);
    for (let key of target) {
      if (target.hasOwnProperty(key)) dist[key] = deepClone(target[key]);
    }
    return dist;
  } else return target;
}
